activiti和设计模式(4)
此次行文是从一个定义好的流程定义开始梳理,然后到流程启动,生成一个流程实例,提交第一个任务,任务完成,实例完成,实例完结。学习其中的设计模式,学习框架的设计的理念。
- 首先是找到流程的定义:
ProcessDefinition def = repositoryService.createProcessDefinitionQuery().processDefinitionId(
workFlowId).processDefinitionTenantId(orgId).singleResult();
有一个需要注意的问题,这种情况下查找的流程定义,ProcessDefinition没有进行解析彻底,只是数据库字段的映射。
- 启动流程实例:
ProcessInstance ins = runtimeService
.startProcessInstanceById(workFlowId, formId,variablesObject);
进入命令行:StartProcessInstanceCmd
public ProcessInstance execute(CommandContext commandContext) {
// 找到部署管理器DeploymentManager
DeploymentManager deploymentManager = commandContext
.getProcessEngineConfiguration()//说明①
.getDeploymentManager();
// Find the process definition
ProcessDefinitionEntity processDefinition = null;
if (processDefinitionId != null) {
processDefinition = deploymentManager.findDeployedProcessDefinitionById(processDefinitionId);//说明②
}
// .......
//这个地方省略了依靠其他参变量寻找processDefiniton的代码
// Do not start process a process instance if the process definition is suspended
if (deploymentManager.isProcessDefinitionSuspended(processDefinition.getId())) {
throw new ActivitiException("Cannot start process instance. Process definition "
+ processDefinition.getName() + " (id = " + processDefinition.getId() + ") is suspended");
}
// Start the process instance
ExecutionEntity processInstance = processDefinition.createProcessInstance(businessKey);//说明③
// now set the variables passed into the start command
initializeVariables(processInstance);//说明④
// now set processInstance name
if (processInstanceName != null) {
processInstance.setName(processInstanceName);
commandContext.getHistoryManager().recordProcessInstanceNameChange(processInstance.getId(), processInstanceName);
}
processInstance.start();//说明⑤
return processInstance;
}
说明①:CommandContext,以及processEngineConfiguration 都是单例的模式,只不过从代码上面看,和一般的单例模式不太一样,找不到private的构造方法。
说明②: 通过部署管理器寻找流程定义的过程:
org.activiti.engine.impl.persistence.deploy.DeploymentManager.
findDeployedProcessDefinitionById(String)
首先是到缓存中查找,如果缓存中没有,再到数据库中查找,这个缓存的大小,可以在引擎的配置文件中配置:
<property name="processDefinitionCacheLimit" value="10" />
通过数据库查找的流程定义依然是没有完全解析的,具体的全部的解析的过程在什么地方呢?
public ProcessDefinitionEntity resolveProcessDefinition(ProcessDefinitionEntity processDefinition) {
String processDefinitionId = processDefinition.getId();
String deploymentId = processDefinition.getDeploymentId();
processDefinition = processDefinitionCache.get(processDefinitionId);
if (processDefinition==null) {
DeploymentEntity deployment = Context
.getCommandContext()
.getDeploymentEntityManager()
.findDeploymentById(deploymentId);//在这个地方拿到具体的流程定义文件,resource红有值了。
deployment.setNew(false);
deploy(deployment, null);//具体的解析发生在这个过程中,activitis填充了解析的内容
processDefinition = processDefinitionCache.get(processDefinitionId);
if (processDefinition==null) {
throw new ActivitiException("deployment '"+deploymentId+"' didn't put process definition '"+processDefinitionId+"' in the cache");
}
}
return processDefinition;
}
说明③:activiti中没有ProcessInstanceEntity,有的只是ExecutionEntity。创建ExecutionEntity的时候,把历史数据全部的创建,并且插入了数据库中。
另外还有流程实例创建的事件广播出去,这个使用的是观察者模式,这个模式在activiti中可谓是到处都是,主要用于事件的通知,订阅之类的。
// 实例数据创建
Context.getCommandContext().getHistoryManager()
.recordProcessInstanceStart(processInstance);
// 事件广播
if (Context.getProcessEngineConfiguration().getEventDispatcher().isEnabled()) {
Context.getProcessEngineConfiguration().getEventDispatcher().dispatchEvent(
ActivitiEventBuilder.createEntityEvent(ActivitiEventType.ENTITY_CREATED, processInstance));
}
说明④:关于流程实例中的变量Variables,需要单独拿出来说明一下。
说明⑤:进入状态机的设计模式
- 上一篇 activiti和设计模式(3)
- 下一篇 activiti和设计模式(5)